package se19team1e.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import se19team1e.dao.abstrakt.jaas.JobAdvertDAO;
import se19team1e.dao.factory.DAOFactorySelector;
import se19team1e.entity.AccountDTO;
import se19team1e.entity.JobAdvertDTO;
import se19team1e.exception.DataAccessException;
import se19team1e.gui.JobAdvertSearchForm;
import se19team1e.search.SearchEngine;
import se19team1e.util.StringUtil;

/**
 * 
 * The Job Advert Search controller class coordinates the operations between the screen, form, and entity objects for job advert search.
 * 
 * @author Arun Manivannan
 *
 */
public class JobAdvertSearchController extends BaseController {

    /**
     * Constructs the controller.
     * 
     * @param application Reference to the current application instance.
     */
    public JobAdvertSearchController( Application application ) {
        super( application );
    }

    /**
     * Initializes the controller.
     * 
     * <p>
     * The job advert search form is set as the current active screen.
     * </p>
     */
    public void initialize() {
        // get screen
        JobAdvertSearchForm screen = this.getApplication().getScreen(JobAdvertSearchForm.class);
        
        // initialize screen
        screen.initialize( this );
        
        // set as active screen
        this.getApplication().setCurrentScreen( screen );
    }

    /**
     * Validates the login credentials and set the current logged in account if successfully.
     * 
     * <p>
     * Displays an error message if it fails, using a message box.
     * </p>
     * @param username Login username credentials.
     * @param password Login password credentials.
     * @return jobAdverts object that is to be loaded
     * @throws DataAccessException 
     */
    public List<JobAdvertDTO> retrieveAll() throws DataAccessException {

    	Map<String, String> filters = getDefaultFilter();
    	
    	List<JobAdvertDTO> jobAdverts = getResultsFromSearchEngine("", filters);
    	
        System.out.println("Job Adverts "+jobAdverts);
        
        return jobAdverts;
        
    }
    
    
    public JobAdvertDTO retrieveById(String id) throws DataAccessException {
    	
    	System.out.println("Input ID : "+id);
        // validate first
        if ( !this.validate(id) ) {
            // failure, return
            displayNoResultsMessage();
        }
            
        JobAdvertDAO jobAdvertDAO = DAOFactorySelector.getDAOFactory().getJobAdvertDAO();
        
        JobAdvertDTO jobAdvertDTO = jobAdvertDAO.retrieveById(id);
        
        System.out.println("Job Advert "+jobAdvertDTO);
        
        if (jobAdvertDTO==null){
            // no such account, display error message
            this.displayNoResultsMessage();
            
        }
        
        return jobAdvertDTO;
        
    }
    
    
    public List<JobAdvertDTO> retrieveByCriteria (String criteria) throws DataAccessException {
    	
    	Map<String, String> filters = getDefaultFilter();
    	
    	System.out.println("Input criteria : "+criteria);
    	if (StringUtil.isEmptyOrNull(criteria)){
    		return new ArrayList<JobAdvertDTO>();
    	}
    	List<JobAdvertDTO> jobAdverts = getResultsFromSearchEngine(criteria,filters);
    	
        return jobAdverts;
        
    }
    
    
    
    /*public List<JobAdvertDTO> retrieveByCriteriaNonAdvertister (String criteria) throws DataAccessException {
    	
    	Map<String, String> filters = getDefaultFilter();
    	filters.put("withdrawn","false");
    	
    	System.out.println("Input criteria : "+criteria);
    	List<JobAdvertDTO> jobAdverts = getResultsFromSearchEngine(criteria,filters);
    	
        return jobAdverts;
        
    }*/
    
    

	private List<JobAdvertDTO> getResultsFromSearchEngine(String criteria, Map<String, String> filters) {
		
		SearchEngine<JobAdvertDTO, String> searchEngine = this.getApplication().getSearchEngine();
		List<JobAdvertDTO> jobAdverts = searchEngine.search(criteria, filters);
		return jobAdverts;
	}

	private Map<String, String> getDefaultFilter() {
		
		Map<String, String> filters=new HashMap<String,String>();
		//System.out.println("Current Account : "+getApplication().getCurrentAccount());
		if (getApplication().getCurrentAdvertiser()!=null){
			filters.put("advertiserId",getApplication().getCurrentAdvertiser().getId());
		}
		else{
			filters.put("withdrawn","false");
		}
    	
		return filters;
	}
    
    
    /**
     * Validates the login credentials to see if it is valid for login.
     * 
     * <p>
     * Returns false if validation fails.
     * </p>
     * <p>
     * Displays an error message if it fails, using a message box.
     * </p>
     * @param username Login username credentials.
     * @param password Login password credentials.
     * @return True if valid.
     */
    private boolean validate(String id) {
    	System.out.println("Validation id : "+id);
        // check for empty entry
        if ( StringUtil.isEmptyOrNull(id)) {
            // failure, display error message
            this.displayMissingInputErrorMessage();
            
            return false;
        }
        
        return true;
    }

    /**
     * Displays a message box indicating that input is missing.
     */
    private void displayMissingInputErrorMessage() {
        this.displayMessage( "Error", "Missing search criteria", new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
               // do nothing
            }
        });
    }

    /**
     * Displays a message box indicating that username is invalid.
     */
    private void displayNoResultsMessage() {
        this.displayMessage( "Info", "No results match your search criteria", new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
               // do nothing
            }
        });
    }

	public Vector<String> getFields() throws DataAccessException {
		
		Vector<String> fieldsHeader=new Vector<String>();
		JobAdvertDAO jobAdvertDAO = DAOFactorySelector.getDAOFactory().getJobAdvertDAO();
		fieldsHeader.addAll(jobAdvertDAO.getFields());
		
		return fieldsHeader;
	}
	
	public Vector<String> getFieldsInUpperCase(Vector<String> fields) {
		
		Vector<String> fieldsInUpperCase=new Vector<String>();
		for (String field : fields) {
			
			fieldsInUpperCase.add(field.toUpperCase());
		}
		return fieldsInUpperCase;
	}
	
	public boolean isAccountLogined(){
		AccountDTO accountName = this.getApplication().getCurrentAccount();
		if(accountName==null){
			return false;
		}	
		return true;
	}
    
    
}
